
package com.tools.cleanmaster.utils;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;

import com.tools.cleanmaster.CleanApplication;
import com.tools.cleanmaster.CleanConstant;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class AppTaskUtils {
    private static AppTaskUtils mAppTaskUtils;
    private static ArrayList<String> sHomeSet = new ArrayList<String>();
    private static final String[] ONEKEY_PROTECTED_LIST = {
            "com.android.providers.", "system", "com.android.phone", "android",
            "com.android.systemui",
    };

    private final ArrayList<PackageChangeListener> mPackageChangeListeners =
            new ArrayList<AppTaskUtils.PackageChangeListener>();

    public interface PackageChangeListener {
        void onPackageRemoved(String pkgName);

        void onPackageAdded(String pkgName);
    }

    private AppTaskUtils() {
    }

    public AppTaskUtils getInstance() {
        if (mAppTaskUtils == null) {
            mAppTaskUtils = new AppTaskUtils();
        }
        return mAppTaskUtils;
    }

    public static String getPackageName(RunningAppProcessInfo amProcess) {
        String pname = amProcess.processName;
        String pkgName = null;
        if (amProcess.pkgList != null) {
            for (String s : amProcess.pkgList) {
                pkgName = s;
                // System.out.println("find pkg(" + pname + ") === " + s);
                if (s.equals(pname)) {
                    return pname;
                }
            }
        }
        if (pkgName == null) {
            pkgName = pname;
        }
        return pkgName;
    }

    public static boolean checkRunningProcess(String pkgName, int uid) {
        if (uid < 10000) {
            // if user id less than 10000, mean system uid, we should skip it.
            return false;
        }
        if (AppTaskUtils.isOneKeyProtected(pkgName)) {
            return false;
        }
        if (CleanConstant.REAL_PACKAGE_NAME.equals(pkgName)) {
            return CleanConstant.SHOW_MYSELF;
        }
        return true;
    }

    public static boolean isOneKeyProtected(String pkgName) {
        for (String item : ONEKEY_PROTECTED_LIST) {
            if (pkgName.equals(item) || (item.endsWith(".") && pkgName.startsWith(item))) {
                return true;
            }
        }
        return false;
    }

    /**
     * clear home package set
     */
    public static synchronized void clearHomePackages() {
        sHomeSet.clear();
    }

    public static void add(String pkgName) {
        if (mAppTaskUtils != null) {
            mAppTaskUtils.newPackageAdded(pkgName);
        }
    }

    private void newPackageAdded(String pkgName) {
        synchronized(mPackageChangeListeners) {
            for (PackageChangeListener l : mPackageChangeListeners) {
                l.onPackageAdded(pkgName);
            }
        }
    }

    public static Map<String, Long> getProgressesMem(ActivityManager activityManager) {
        Map<String, Long> pkgMemMap = new HashMap<String, Long>();
        Map<Integer, String> pidPkgMap = new HashMap<Integer, String>();//pid与pkgName的map
        // 先获取pid集合，再根据pid获取内存
        List<RunningAppProcessInfo> runProcessList = activityManager.getRunningAppProcesses();
        if (runProcessList != null) {
            for (ActivityManager.RunningAppProcessInfo amProcess : runProcessList) {
                String pkgName = AppTaskUtils.getPackageName(amProcess);
                if (!AppTaskUtils.checkRunningProcess(pkgName, amProcess.uid)) {
                    continue;
                }
                pidPkgMap.put(amProcess.pid, pkgName);
            }
        }
        List<ActivityManager.RunningServiceInfo> runServiceList = activityManager.getRunningServices(100);
        if (runServiceList != null) {
            for (ActivityManager.RunningServiceInfo amService : runServiceList) {
                if (!amService.started || amService.restarting > 0) {
                    // Skip services which are not started or are restarting
                    continue;
                }
                String pkgName = amService.service.getPackageName();
                if (!AppTaskUtils.checkRunningProcess(pkgName, amService.uid)) {
                    continue;
                }
                pidPkgMap.put(amService.pid, pkgName);
            }
        }
        // 将pid转化为静态数组
        Set<Integer> pidsInteger = pidPkgMap.keySet();
        if (pidsInteger.isEmpty()) {
            return pkgMemMap;
        }
        int[] pids = new int[pidsInteger.size()];
        int index = 0;
        for (Integer pid : pidsInteger) {
            pids[index] = pid;
            index++;
        }
        // 获取内存
        int[] processMemUsage = MemoryUtils.getProcessMemUsage(CleanApplication.getInstance(), pids);
        for (int i = 0; i < processMemUsage.length; i++) {
            long size = processMemUsage[i];
            String pkgName = pidPkgMap.get(pids[i]);
            if (pkgMemMap.containsKey(pkgName)) {
                pkgMemMap.put(pkgName, pkgMemMap.get(pkgName) + size);
            } else {
                pkgMemMap.put(pkgName, size);
            }
        }
        return pkgMemMap;
    }
}
